#define _CRT_SECURE_NO_WARNINGS // 预处理指令，用于告诉编译器忽略与安全性相关的警告
#include "test40_ThreadTest.h"
#include <iostream>
// iostream  = 标准输入输出头文件，std::cout（用于输出到控制台）、std::cin（用于从控制台输入）和std::cerr（用于输出错误信息）
#include <sstream> // 
#include <string>
#include <vector>
#include <thread> // 创建和管理多线程，"thread"头文件还提供了一些同步原语，如互斥锁（mutex）、条件变量（condition_variable）等，用于实现线程之间的同步和通信
#include <chrono> // 用于测量时间、计算时间差以及进行时间点 std::chrono 和 std::time 等
#include <ctime>


// c++多线程 参考
// https://blog.csdn.net/Long_xu/article/details/127919041

int test40_ThreadTest::classMain()
{
	std::cout << "test40_ThreadTest - <thread>" << "\n";

	int stature = 0;
	std::string result = "中文";
	std::cout << "ִ输出：" << result << "\n";

	this->test();

	// 多线程测试 = 线程池法
	const int numThreads = 5; // 静态数据，常量
	std::thread threads[numThreads]; // 线程池

	// 循环让线程调用工作函数
	for (int i = 0; i < numThreads; ++i) {
		threads[i] = std::thread(&test40_ThreadTest::threadFunction, this, i); // 线程调用工作函数
	}

	// 给每个线程设置属性 = 等待工作函数执行完毕
	for (int i = 0; i < numThreads; ++i) {
		threads[i].join(); // detach和join的区别 = 分离线程/detach和等待/join所有线程结束
	}
	// 有问题？？？
	//int c = 10;
	//std::thread t3;
	//t3(&test40_ThreadTest::threadFunction2, this,ref(c)); // 
	//t3.join();
	//cout << "main --> 3 : &c = " << &c << ", c = " << c << endl;

	std::cout << "All threads have completed." << std::endl;

	return 0;

}

void test40_ThreadTest::test()
{
	std::cout << "40中的函数---当前日期为" << "\n";
	time_t t = time(nullptr); // 从1970年开始的毫秒数
	struct tm* now = localtime(&t); // 只能到秒

	std::stringstream timeStr; // 字符串缓冲区，把其他类型转为字符串

	// 当前日期为
	timeStr << now->tm_year + 1900 << "年";
	timeStr << now->tm_mon + 1 << "月";
	timeStr << now->tm_mday << "日 ";
	timeStr << now->tm_hour << ":"; // 时
	timeStr << now->tm_min << ":"; // 分
	timeStr << now->tm_sec; // 秒
	
	timeStr << "\n"; // 末尾加入换行符

	std::cout << timeStr.str();

}

// 线程中的工作函数
void test40_ThreadTest::threadFunction(int id) {
	std::chrono::milliseconds duration(100); // 让多个线程依次顺序执行
	std::this_thread::sleep_for(duration); // 让线程休眠
	std::cout << " 线程参数为：" << id << " 线程id为：" << std::this_thread::get_id()
		<< std::endl;
	std::cout << "    当前线程时间为=";
	// 从1970.01.01零时开始经过一定时间后得到的
	std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

	// 转成c风格的时间类型
	std::time_t t = std::chrono::system_clock::to_time_t(now);

	// c风格的时间
	std::tm* localTime = std::localtime(&t);
	std::cout << "Current time: "
		<< localTime->tm_year + 1900 << '-'
		<< localTime->tm_mon + 1 << '-'
		<< localTime->tm_mday << ' '
		<< localTime->tm_hour << ':'
		<< localTime->tm_min << ':'
		<< localTime->tm_sec << std::endl;
	//std::cout << "now" << now << std::endl;
	//std::cout << "t" << t << std::endl;
	
	// 精确时间
	// 获取当前系统时间点
	auto myNow = std::chrono::system_clock::now();

	std::time_t myTimestamp = std::chrono::system_clock::to_time_t(myNow); // 将时间点转换为时间戳
	auto ms = std::chrono::time_point_cast<std::chrono::milliseconds>(myNow); // 将时间点转换为毫秒数
	auto us = std::chrono::time_point_cast<std::chrono::microseconds>(myNow); // 将时间点转换为微秒数
	auto ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(myNow); // 将时间点转换为纳秒数

	// time_since_epoch()函数获取时间点相对于纪元（Epoch）的持续时间，并使用count()函数获取毫秒数部分
	// 这种方式获取的毫秒数是相对于纪元（Epoch）的偏移量
	auto MStimestamp = ms.time_since_epoch().count(); // 获取毫秒数部分
	auto UStimestamp = us.time_since_epoch().count(); // 获取微秒数部分
	auto NStimestamp = ns.time_since_epoch().count(); // 获取纳秒数部分

	// 输出时间戳
	std::cout << "    当前时间戳：" << myTimestamp << std::endl;
	std::cout << "    当前毫秒数：" << MStimestamp << std::endl;
	std::cout << "    当前微秒数：" << UStimestamp << std::endl;
	std::cout << "    当前纳秒数：" << NStimestamp << std::endl;

}

// 线程中的工作函数
void test40_ThreadTest::threadFunction2(int& c) {
	std::cout << "threadFunction2(): &c = " << &c;
	std::cout << " --> c + 10 =" << (c += 10) << std::endl;
}


